package com.ruoyi.web.controller.admin.auth;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.AdminUserDO;
import com.ruoyi.common.core.domain.entity.MenuDO;
import com.ruoyi.common.core.domain.entity.RoleDO;
import com.ruoyi.common.enums.CommonStatusEnum;
import com.ruoyi.common.utils.StpSystemUtil;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.collection.CollectionUtils;
import com.ruoyi.newSystem.bean.output.AuthPermissionInfoRespVO;
import com.ruoyi.newSystem.service.AdminUserService;
import com.ruoyi.newSystem.service.PermissionService;
import com.ruoyi.newSystem.service.RoleService;
import com.ruoyi.newSystem.service.impl.MenuServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;

/**
 * 认证控制器
 */
@RestController
@RequestMapping("/auth")
@RequiredArgsConstructor
@Slf4j
public class AuthController {


    private final AdminUserService userService;

    private final PermissionService permissionServiceImpl;

    private final RoleService roleServiceImpl;

    private final MenuServiceImpl menuServiceImpl;


    /**
     * 用户用户权限信息
     *
     * @return the permission info
     */
    @GetMapping("/getPermissionInfo")
    public AjaxResult getPermissionInfo() throws Exception {
        // 1.1 获得用户信息
        Long loginIdAsLong = StpSystemUtil.getLoginIdAsLong();
        AdminUserDO user = userService.getUserByUserId(loginIdAsLong);
        if (user == null) {
            throw new Exception("用户不存在");
        }
        AuthPermissionInfoRespVO authPermissionInfoRespVO = new AuthPermissionInfoRespVO();


        // 1.2 获得角色列表
        Set<Long> roleIds = permissionServiceImpl.getUserRoleIdListByUserId(loginIdAsLong);
        List<RoleDO> roles = roleServiceImpl.getRoleList(roleIds);
        //剔除没有启动的角色
        roles.removeIf(role -> !CommonStatusEnum.ENABLE.getStatus().equals(role.getStatus())); // 移除禁用的角色
        HashSet<String> objects = new HashSet<>();
        //将数据权限解析出来
        for (RoleDO role : roles) {
            String dataScopeDatasetIds = role.getDataScopeDatasetIds();
            if (StringUtils.isBlank(dataScopeDatasetIds)) {
                continue;
            }
            JSONObject parse = JSONObject.parse(dataScopeDatasetIds);

            parse.forEach((item, object) -> {
                JSONArray item1 = (JSONArray) object;
                List<String> list = item1.toList(String.class);
                objects.addAll(list);
            });
        }
        authPermissionInfoRespVO.setDatasetIds(JSONObject.toJSONString(objects));
        if (CollectionUtil.isEmpty(roles)) {
            log.info("无角色信息");
            throw new Exception("用户无任何角色");
        }
        authPermissionInfoRespVO.setRoles(new HashSet<>(StpSystemUtil.getRoleList()));
        roleIds = CollectionUtils.convertSet(roles, RoleDO::getId);
        // 1.3 获得菜单列表
        Set<Long> menuIds = permissionServiceImpl.getRoleMenuListByRoleId(roleIds);
        if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(menuIds)) {
            List<MenuDO> menuList = menuServiceImpl.getMenuList(menuIds);
            menuList.removeIf(menu -> !CommonStatusEnum.ENABLE.getStatus().equals(menu.getStatus())); // 移除禁用的菜单
            menuList.sort(Comparator.comparing(MenuDO::getSort));
            List<AuthPermissionInfoRespVO.MenuVO> menuVOS = new ArrayList<>();

            menuList.forEach(menu -> {
                AuthPermissionInfoRespVO.MenuVO menuVO = new AuthPermissionInfoRespVO.MenuVO();
                BeanUtils.copyProperties(menu, menuVO);
                menuVOS.add(menuVO);
            });
            authPermissionInfoRespVO.setMenus(buildTree(menuVOS));
        } else {
            log.info("无菜单信息");
            throw new Exception("用户无菜单信息");
        }

        authPermissionInfoRespVO.setAvatar(user.getAvatar());
        authPermissionInfoRespVO.setNickname(user.getNickname());
        authPermissionInfoRespVO.setPermissions(new HashSet<>(StpSystemUtil.getPermissionList()));
        // 2. 拼接结果返回
        return AjaxResult.success(authPermissionInfoRespVO);
    }


    /**
     * 将 List 数据构建成树形结构
     */
    private List<AuthPermissionInfoRespVO.MenuVO> buildTree(List<AuthPermissionInfoRespVO.MenuVO> dataList) {
        // 1. 创建 Map 存储所有节点，key 为 id
        Map<Long, AuthPermissionInfoRespVO.MenuVO> nodeMap = new HashMap<>();
        for (AuthPermissionInfoRespVO.MenuVO item : dataList) {
            nodeMap.put(item.getId(), item);
        }

        // 2. 存储根节点
        List<AuthPermissionInfoRespVO.MenuVO> rootNodes = new ArrayList<>();

        // 3. 构建父子关系
        for (AuthPermissionInfoRespVO.MenuVO item : dataList) {
            AuthPermissionInfoRespVO.MenuVO node = nodeMap.get(item.getId());
            Long parentId = item.getParentId();

            // 如果 parentId 为 "0" 或 null 或空字符串，说明是根节点
            if (1 == parentId) {
                rootNodes.add(node);
            } else if (0 != parentId) {
                // 找到父节点并添加子节点
                AuthPermissionInfoRespVO.MenuVO parentNode = nodeMap.get(parentId);
                if (parentNode != null) {
                    List<AuthPermissionInfoRespVO.MenuVO> children = parentNode.getChildren();
                    children.add(node);
                    parentNode.setChildren(children);
                }
            }
        }

        return rootNodes;
    }


    /**
     * 获取用户信息 请求会带请求token 进来
     *
     */
    @GetMapping("/getUser")
    public AjaxResult getUser() {
        Long loginIdAsLong = StpSystemUtil.getLoginIdAsLong();
        AdminUserDO user = userService.getUserByUserId(loginIdAsLong);
        return AjaxResult.success(user);
    }
}
